home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
archiver
/
lsize25.zip
/
LSIZE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-18
|
26KB
|
717 lines
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <dir.h>
#define BUF_SIZ 2048
#define BSIZE 32760
#define MAX_SUB_FILES 4000
#define demand(fact, remark) {\
if (!(fact)) {\
fprintf(stderr, "\nError -> " #fact "\n");\
fprintf(stderr, #remark "\n");\
perror("error");\
fcloseall();\
_setcursortype(_NORMALCURSOR);\
abort();\
exit(1);\
}\
}
/************************** Variables *************************************/
char buffer[BUF_SIZ]; /* buffer for reading and writing files */
char outbuf[BSIZE]; /* disk output buffer */
typedef struct{ /* Structure to hold file info */
unsigned long int position; /* location of file in LZH from beginning */
char filenum; /* subfile number file will be written to */
unsigned long int size; /* file size */
char *name; /* file name - allocated dynamically */
unsigned long int size2;
unsigned long int position2;
} record;
record *file[MAX_SUB_FILES]; /* array of pointers to file records */
unsigned long int fsize; /* used to hold various file sizes */
unsigned long int nsize[256]; /* subfile lengths */
unsigned long int i; /* iteration variable */
unsigned long int skip; /* used to hold skip file length */
unsigned long int ovrwrt; /* overwrite flag(0=dont ovrwrt) */
unsigned long int tsize; /* target file size(max for subfiles */
unsigned long int bcount; /* byte count: used for file buffer */
unsigned int position;
unsigned int skipper;
unsigned int fsize2;
unsigned int rotaten;
char flag;
unsigned long int startdir=0;
unsigned long int dirsize=0;
char *strptr;
unsigned char subfile; /* subfile number */
unsigned char max; /* max = total number of subfiles */
int count; /* count = number of files in archive */
int count2;
int str_len;
unsigned long int total_size; /* accumulator -total size of a subfile */
unsigned int hsize; /* header size */
int j,k; /* loop counters */
char temp[MAXPATH]; /* temp string storage */
char prefix[MAXPATH]; /* prefix for target files */
char suffix[4]; /* holds subfile number suffix 1,2,3,...*/
char ifile[MAXPATH]; /* name of source file */
char tfile[MAXPATH]; /* temp storage for manip file names*/
char ans; /* answer for: Overwrite file? */
char drive[MAXDRIVE];
char dir[MAXDIR];
char comment[85];
char iname[MAXFILE];
char oname[MAXFILE+8];
char ext[MAXEXT];
char saveext[MAXEXT];
int flags;
char trunc_flag=0;
FILE *fp,*sfp;
void sortfs(void);
void help(void);
/********* MAIN PROGRAM **********/
void main(int argc, char *argv[]) /** argc = number of command line args ***/
{ /**** argv = array containing actual args **/
int lastarg=argc-1;
if(argc<3) help();
if(strtol(argv[lastarg],NULL,10)<0)
{ puts("Error: Invalid file size"); exit(1);}
if(!strcmp(argv[lastarg],"1.44M") || !strcmp(argv[lastarg],"1.44m")\
|| !strcmp(argv[lastarg],"1.4M")|| !strcmp(argv[lastarg],"1.4m")) tsize=1457664;
else if(!strcmp(argv[lastarg],"720K") || !strcmp(argv[lastarg],"720k")) tsize=730112;
else if(!strcmp(argv[lastarg],"1.2M") || !strcmp(argv[lastarg],"1.2m")) tsize=1457664;
else if(!strcmp(argv[lastarg],"360K") || !strcmp(argv[lastarg],"360k")) tsize=362496;
else tsize=strtoul(argv[lastarg],NULL,10);
if(tsize<=0) help();
strcpy(ifile,argv[1]);
flags=fnsplit(ifile,drive,dir,iname,ext);
if(!(flags & EXTENSION)){ /* If no extension on source file */
strcpy(tfile,ifile);
strcat(tfile, ".LZH"); // try LZH
fp=fopen(tfile, "rb");
if(!fp){
strcpy(tfile,ifile);
strcat(tfile, ".ARJ"); // try ARJ
fp=fopen(tfile, "rb");
}
if(!fp){
strcpy(tfile,ifile); // try ZIP
strcat(tfile, ".ZIP");
fp=fopen(tfile, "rb");
}
strcpy(ifile, tfile);
fclose(fp);
}
fp=fopen(ifile, "rb"); // Open source file
demand(fp!=NULL, Could not open source file);
strupr(ifile); // conv to upper case
flags=fnsplit(ifile,drive,dir,iname,ext);
strcpy(saveext, ext); // save file name extension
/********************************* Search LZH file ************************/
/*
1 byte - header size
1 byte - header checksum
5 bytes - file header/signature
4 bytes - compressed size
4 bytes - original size
4 bytes - date/time
2 bytes - file attributes
n bytes - file path\name (ends with x00)
n bytes - file data
.
.
.
*/
printf("\n...searching file %s\n",ifile);
skip=0;
count=0;
if(!strcmp(ext,".LZH")) {
while(!feof(fp)){
demand(count<MAX_SUB_FILES, Sorry - Too many files in LZH);
file[count]=malloc(sizeof(record));
demand(file[count]!=NULL, Out of memory);
file[count]->position=skip;
hsize=fgetc(fp);
demand(!ferror(fp),Read error);
if(hsize==0) break;
if(feof(fp)) break;
fgetc(fp);
if(feof(fp)) break;
fgets(temp,6,fp);
demand(!strncmp(temp,"-lh",3),LZH file has problems);
fread(&fsize,sizeof(long),1,fp);
file[count]->size=fsize+hsize+2;
file[count]->filenum=0;
skip+=file[count]->size;
fseek(fp, (long)10, SEEK_CUR);
fgets(temp,fgetc(fp)+1,fp);
file[count]->name = malloc(strlen(temp)+1);
demand(file[count]->name!=NULL, Out of memory!);
strcpy(file[count]->name, temp);
count++;
fseek(fp, fsize+5, SEEK_CUR);
}
}
/*********************** SEARCH ARJ FILE **********************************
ARJ archives contains two types of header blocks:
Archive main header - This is located at the head of the archive
Local file header - This is located before each archived file
Structure of main header (low order byte first):
Bytes Description
----- -------------------------------------------------------------------
2 header id (main and local file) = 0x60 0xEA
2 basic header size (from 'first_hdr_size' thru 'comment' below)
= first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
= 0 if end of archive
maximum header size is 2600
1 first_hdr_size (size up to and including 'extra data')
1 archiver version number
1 minimum archiver version to extract
1 host OS (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MAC-OS)
(5 = OS/2, 6 = APPLE GS, 7 = ATARI ST, 8 = NEXT)
(9 = VAX VMS)
1 arj flags
(0x01 = NOT USED)
(0x02 = OLD_SECURED_FLAG)
(0x04 = VOLUME_FLAG) indicates presence of succeeding
volume
(0x08 = NOT USED)
(0x10 = PATHSYM_FLAG) indicates archive name translated
("\" changed to "/")
(0x20 = BACKUP_FLAG) indicates backup type archive
(0x40 = SECURED_FLAG)
1 security version (2 = current)
1 file type (must equal 2)
1 reserved
4 date time when original archive was created
4 date time when archive was last modified
4 archive size (currently used only for secured archives)
4 security envelope file position
2 filespec position in filename
2 length in bytes of security envelope data
2 (currently not used)
? (currently none)
? filename of archive when created (null-terminated string)
? archive comment (null-terminated string)
4 basic header CRC
2 1st extended header size (0 if none)
? 1st extended header (currently not used)
4 1st extended header's CRC (not present when 0 extended header size)
Structure of local file header (low order byte first):
Bytes Description
----- -------------------------------------------------------------------
2 header id (main and local file) = 0x60 0xEA
2 basic header size (from 'first_hdr_size' thru 'comment' below)
= first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
= 0 if end of archive
maximum header size is 2600
1 first_hdr_size (size up to and including 'extr